import { defineStore } from "pinia"
import { reactive, watch } from "vue"
import { Entity, Word } from "../model"
import { getData, updateWord } from "./db"
import { toArray } from "../utils"

export const useWordStore = defineStore("word", () => {
    const words: Entity<Word>[] = reactive([])

    const wordMap: Map<string, Entity<Word>> = new Map()

    const unlearnedWords: Entity<Word>[] = reactive([])

    const data = getData()
    data.words.forEach(addWord)

    function addWord(w: Entity<Word>) {
        w = reactive(w)
        words.push(w)
        wordMap.set(w.word, w)
        if (!w.learned) {
            unlearnedWords.push(w)
        }

        watch(w, updateWord)
    }

    function setWordLearned(word: Entity<Word>) {
        if (!word.learned) {
            word.learned = true
        }
        const index = unlearnedWords.indexOf(word)
        if (index >= 0) {
            unlearnedWords.splice(index, 1)
        }
    }

    function getWord(w: string) {
        const word = wordMap.get(w)
        if (!word) {
            throw `word not find:${w}`
        }
        return word
    }

    function getSimpleMeaningString(word: Word): string {
        try {
            const meaningStrings: string[] = []
            toArray(word.meanings).forEach((m) => {
                if (!meaningStrings.includes(m.meaning))
                    meaningStrings.push(m.meaning)
            })
            return meaningStrings.reduce((p, c) => `${p} ${c};`)
        } catch (e) {
            console.log(word)

            return "error"
        }
    }

    function getMeaningMap(word: Word): Map<string, string[]> {
        const map: Map<string, string[]> = new Map()
        toArray(word.meanings).forEach((m) => {
            let v = map.get(m.wordClass)
            if (!v) {
                v = []
                map.set(m.wordClass, v)
            }
            v.push(m.meaning)
        })
        return map
        // const list = Array.from(map.entries()).map(([c, m]) => {
        //     const ms = m.reduce((p, c) => p + ";" + c)
        //     return c + " " + ms
        // })
        // return list.sort((a, b) => a.length - b.length)
        // return list
    }

    return {
        words,
        wordMap,
        unlearnedWords,
        getWord,
        getSimpleMeaningString,
        getMeaningMap,
        setWordLearned,
    }
})
